
#pragma once

// c++ std
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// linux
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>


// 从网络字节IP地址 转换 为字符串
char * InternetToHost(struct sockaddr_in * sa, char * buffer, size_t buffer_length) {

    bzero(buffer, buffer_length);
    inet_ntop(sa->sin_family, &sa->sin_addr, buffer, buffer_length);
    return buffer;
}

// 根据 address 连接到对应的服务
int TcpConnect(const char * ip, uint16_t port) {

    struct sockaddr_in sai;
    bzero(&sai, sizeof(sai));

    sai.sin_family = AF_INET;
    sai.sin_port   = htons(port);
    inet_pton(sai.sin_family, ip, &sai.sin_addr);

    int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sockfd < 0) {

        printf("create sockfd failure.\n");
        return -1;
    }
    if (connect(sockfd, (struct sockaddr * )&sai, sizeof(sai)) == 0) {

        // connect success
        return sockfd;
    }
    return -1;
}

int Connect(struct sockaddr * sa, socklen_t sa_len, int sockfd) {

    if (connect(sockfd, sa, sa_len) == 0) {

        return 0;
    }
    return -1;
}

// 获取当前机器的IP地址
int GetServerAddressInformation(const char * name, const char * service) {


    struct addrinfo hints;
    struct addrinfo * result_address;

    hints.ai_family   = AF_UNSPEC;
    hints.ai_flags    = AI_PASSIVE;
    int result = getaddrinfo(name, service, &hints, &result_address);

    struct addrinfo * ptr = result_address;
    for (; ptr != NULL; ptr = ptr->ai_next) {

        if (ptr->ai_addrlen == sizeof(struct sockaddr_in)) {

            struct sockaddr_in * addr_ptr = (struct sockaddr_in * )ptr->ai_addr;
            static char buffer[100];
            printf("%s\n", InternetToHost(addr_ptr, buffer, 100));
        }
    }
    freeaddrinfo(result_address);
    return result;
}
